package com.csist.easyExcel.readListener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson2.JSON;
import com.csist.pojo.excel.CompleteData;
import com.csist.pojo.excel.CompleteDataConverted;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @ClassName CompleteDataListener
 * @Description 【自行描述】
 * @Author Yingru Yu
 * @Date 2024/6/14 8:24
 * @Version 1.0
 */
//这个注解可以为这个类生成一个日志对象，要输出log可以直接用log.等级(信息)输出
@Slf4j
public class CompleteDataConvertedListener implements ReadListener<CompleteDataConverted> {
    /**
     * 每隔多少条数据存储数据库，然后清理缓存
     */
    private static final Integer BATCH_SIZE = 100;

    /**
     * 缓存的数据
     */
    private List<CompleteDataConverted> cacheList = ListUtils.newArrayListWithExpectedSize(BATCH_SIZE);

    /**
     * 无参构造器
     */
    public CompleteDataConvertedListener() {
    }

    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     */
    // private CompleteDataDao completeDataDao;
    // public CompleteDataListener(CompleteDataDAO completeDataDAO) {
    //     this.completeDataDAO = completeDataDAO;
    // }

    /**
     * 每条数据解析
     * @param completeData 一行数据：同{@link AnalysisContext#readRowHolder()}
     * @param analysisContext
     */
    @Override
    public void invoke(CompleteDataConverted completeData, AnalysisContext analysisContext) {
        log.info("当前处理的第"+analysisContext.readRowHolder().getRowIndex()+"行数据");
        log.info("解析到一条数据"+JSON.toJSONString(completeData));
        cacheList.add(completeData);
        // 当缓存集合里面数据量达到预设值时，将数据存储到数据库里面并清空缓存集合，防止几万条数据全部进内存
        if(cacheList.size()>=BATCH_SIZE){
            saveAndClearCacheList();
        }
    }

    /**
     * 所有数据处理完了都会来调用这个方法
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //这里也要存储数据，防止有遗留数据被忘在缓存中没有存进数据库
        saveAndClearCacheList();
    }

    /**
     * 对缓存的数据进行操作并清空
     */
    private void saveAndClearCacheList(){
        log.info("开始处理已缓存的数据");
        cacheList.forEach(e->log.info("正在处理数据："+e.toString()));
        //处理完成后清空缓存
        log.info("已缓存数据处理完成，开始清除缓存数组");
        cacheList = ListUtils.newArrayListWithExpectedSize(BATCH_SIZE);
    }
}
